package ru.spb.nicetu.schoolproject.data;

import org.hibernate.Session;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

import javax.persistence.PersistenceException;

/**
 * Created by dchernyshov on 07.04.15.
 */
public class HibernateUtil {
    public static HibernateUtil instance;

    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static Configuration conf = new AnnotationConfiguration();
    private static org.hibernate.SessionFactory sessionFactory;

    static
    {
        try {
            sessionFactory = conf.configure().buildSessionFactory();
        }
        catch (ExceptionInInitializerError e) {
            System.err.println("%%%% ERRO AO CRIAR O SESSION FACTORY! %%%%");
            e.printStackTrace();
        }
    }


    //CONSTRUCTOR

    // Singleton
    private HibernateUtil()
    {
    }


    //BEHAVIORS
    public synchronized static HibernateUtil getInstance()
    {
        if (HibernateUtil.instance == null)
        {
            HibernateUtil.instance = new HibernateUtil();
        }
        return HibernateUtil.instance;
    }

    // ------------------------------------------------------------------------------------------/

    /**
     * Returns the ThreadLocal Session instance. Lazy initialize the
     * <code>SessionFactory</code> if needed.
     *
     * @return Session
     * @throws PersistenceException
     */
    public Session getSession() throws PersistenceException
    {
        Session session = (Session) threadLocal.get();

        if (session == null || !session.isOpen())
        {
            if (sessionFactory == null)
            {
                rebuildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession() : null;
            threadLocal.set(session);
        }
        return session;
    }

    /**
     * Rebuild hibernate session factory
     */
    public static void rebuildSessionFactory()
    {
        try
        {
            conf.configure();
            sessionFactory = conf.buildSessionFactory();
        }
        catch (Exception e)
        {
            System.err.println("%%%% ERRO AO CRIAR O SESSION FACTORY! %%%%");
            e.printStackTrace();
        }
    }

    /**
     * Close the single hibernate session instance.
     *
     * @throws PersistenceException
     */
    public static void closeSession() throws PersistenceException
    {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null)
        {
            session.close();
        }
    }

    /**
     * return session factory
     *
     */
    public static org.hibernate.SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }

    // ----------------------------------------------------------------//

    public void beginTransaction() throws PersistenceException
    {
        getSession().beginTransaction();
    }

    public void commit() throws PersistenceException
    {
        getSession().getTransaction().commit();
        closeSession();
    }

    public void roolback() throws PersistenceException
    {
        getSession().getTransaction().rollback();
        closeSession();
    }
}
